<!--
 * @Author: Lw
 * @Date: 2022-07-27 14:34:33
 * @LastEditors: LHL
 * @LastEditTime: 2022-10-18 10:45:19
-->
<template>
  <div ref="mapRef">
    <n-spin :show="loading" class="spin"></n-spin>
  </div>
</template>

<script setup>
import AMapLoader from '@amap/amap-jsapi-loader'
import setting from '@/settings/projectSetting'
import { ref, watch, onMounted, nextTick } from 'vue'

const emit = defineEmits(['click', 'markerClick'])
const props = defineProps({
  setMode: {
    type: Boolean,
    default: false,
  },
  markers: {
    type: Array,
    default: () => [],
  },

  lineMarkers: {
    type: Array,
    default: () => [],
  },
  controlMouseOver: {
    //控制事件
    type: Array,
    default: () => [
      { key: 'jing', value: false },
      { key: 'line', value: false },
      { key: 'map', value: true },
    ],
  },
  // 是否地图点击时更换图标
  isMaKerClickChange: {
    type: Boolean,
    default: true,
  },
  // 是否使用自定义窗口弹窗,默认使用系统默认
  windisCustom: {
    type: Boolean,
    default: false,
  },
  defaultIcon: {
    type: String,
    default: new URL(`/img/AMap/mark_bs.png`, import.meta.url).href,
  },
  activeIcon: {
    type: String,
    default: new URL(`/img/AMap/mark_red.png`, import.meta.url).href,
  },
})
watch(
  () => props.markers,
  (markers) => {
    if (Map) {
      // ！！！这里最好要加个防抖，但是我加过不生效，以后再说
      nextTick(() => {
        setMarker()
      })
    }
  },
  { deep: true },
)

watch(
  () => props.lineMarkers,
  (lineMarkers) => {
    console.log('进来啦')
    if (Map) {
      // ！！！
      nextTick(() => {
        setLine()
      })
    }
  },
  { deep: true },
)
// 方法实例
let lineLabel = null
let markerLabel = null
let amap = null
let Map = null
let oldOverlay = []
let MarkerArr = []
let LIneMarkArr = []

let geocoder = null
let infoWindow = null
const mapRef = ref()
const mapConfig = {
  center: [119.293961, 26.061637],
  resizeEnable: true,
  zoom: 11,
}
const loading = ref(false)
onMounted(() => {
  loading.value = true
  AMapLoader.load({
    key: setting.amapKey, // key
    plugins: [
      'AMap.Geolocation',
      'AMap.Autocomplete',
      'AMap.PlaceSearch',
      'AMap.Scale',
      'AMap.OverView',
      'AMap.ToolBar',
      'AMap.MapType',
      'AMap.PolyEditor',
      'AMap.CircleEditor',
      'AMap.Geocoder',
    ], // 插件
    version: '2.0',
    Loca: {
      // 是否加载 Loca， 缺省不加载
      version: '2.0.0', // Loca 版本，缺省 1.3.2
    },
  })
    .then((AMap) => {
      amap = AMap
      Map = new AMap.Map(mapRef.value, mapConfig)
      infoWindow = new AMap.InfoWindow({ isCustom: props.windisCustom, offset: new AMap.Pixel(0, -30) })
      Map.clearMap()
      MarkerArr.length = 0
      Map.on('click', mapClick)
      setMarker()
      setLine()
      AMap.plugin(['AMap.Geocoder'], function () {
        //加载地理编码插件
        geocoder = new AMap.Geocoder({
          radius: 1000, //以已知坐标为中心点，radius为半径，返回范围内兴趣点和道路信息
          extensions: 'all', //返回地址描述以及附近兴趣点和道路信息，默认“base”
        })
      })
    })
    .catch((e) => {
      console.log(e)
    })
    .finally(() => {
      loading.value = false
    })
})
// 生成标记
const setMarker = () => {
  Map.remove(MarkerArr) //清除指定的marker
  MarkerArr.length = 0
  if (props.markers?.length > 0) {
    props.markers.forEach((marker) => {
      if (marker.lnglat) {
        const { lnglat: markerLngLat, title, icon, iconSize, id, data, label } = marker
        const lnglat = markerLngLat.split(',')
        const Marker = new amap.Marker({
          position: lnglat,
          extData: { title: title, id: id, oldIcon: icon, data: data },
          icon: icon ? new amap.Icon(icon) : marker.active ? props.activeIcon : props.defaultIcon,
          offset: iconSize ? new amap.Pixel(-iconSize[0] / 2, -iconSize[1]) : new amap.Pixel(-9, -30), //设置文本标注偏移量
        })
        if (label) {
          Marker.setLabel({
            content: '<span>' + label + '</span>', //设置文本标注内容
            direction: 'bottom', //设置文本标注方位
            offset: new amap.Pixel(0, 2), //设置文本标注偏移量
          })
        }
        Marker.on('click', markerClick)
        const isMouse = props.controlMouseOver.find((item) => {
          return item.key == 'jing'
        })
        if (isMouse.value) {
          Marker.on('mouseover', markerMouseOver)
          Marker.on('mouseout', markerMouseOut)
        }
        MarkerArr.push(Marker)
        Map.add(Marker)
      }
    })
    Map.setFitView(MarkerArr, true)
  }
}
const mapClick = (e) => {
  if (props.setMode && e) {
    const params = {
      longitude: e.lnglat.lng,
      latitude: e.lnglat.lat,
    }
    if (geocoder) {
      geocoder?.getAddress(e.lnglat, function (status, result) {
        params.adcode = result.regeocode?.addressComponent.adcode
        params.address = result.regeocode?.formattedAddress
        emit('click', params)
      })
    } else {
      emit('click', params)
    }
  }
}
const markerClick = (e) => {
  if (props.setMode) {
    const {
      target: { _amap_id: id },
    } = e
    const index = MarkerArr.findIndex((marker) => {
      const { _amap_id } = marker
      return id === _amap_id
    })
    if (index != -1) {
      if (!props.isMaKerClickChange) {
        emit('markerClick', props.markers[index])
        return
      }
      MarkerArr.forEach((marker) => {
        marker.setIcon(props.defaultIcon)
      })
      e.target.setIcon(new URL(`/img/AMap/mark_red.png`, import.meta.url).href)
      emit('markerClick', props.markers[index])
    }
  }
}

function setLine() {
  if (LIneMarkArr?.length) {
    Map.remove(LIneMarkArr)
  }
  LIneMarkArr.length = 0
  if (props.lineMarkers?.length > 0) {
    props.lineMarkers.forEach((line) => {
      if (line.path) {
        const Line = new amap.Polyline({
          path: line.path,
          strokeColor: '#78AEEF',
          strokeWeight: 3,
          isOutline: true,
          strokeOpacity: 1,
          borderWeight: 1,
          outlineColor: '#438FFF',
          extData: { title: line.title, id: line.id, data: line.data, color: line.color },
        })

        const isMouse = props.controlMouseOver.find((item) => {
          return item.key == 'line'
        })
        if (isMouse.value) {
          Line.on('mouseover', lineMouseOver)
          Line.on('mouseout', lineMouseOut)
        }
        LIneMarkArr.push(Line)
      }
    })

    Map.add(LIneMarkArr)
    // Map.setFitView()
  }
}

//鼠标移入展示信息-针对点
const markerMouseOver = (e) => {
  const Marker = e?.target || {}
  console.log('Marker?.getExtData()?.data : ', Marker?.getExtData()?.data)
  const { keyName, latitude, longitude, pipeLineName, name, deviceName, code, deviceCode, assetDto } =
    Marker?.getExtData()?.data || {}
  const gxNmae = name || deviceName
  const gxCode = code || deviceCode
  const pName = keyName === 'device' ? '设备' : '井'
  const wellLine = `<div><span style='color:#8A93A9'>所属管线：</span>${pipeLineName || '-'}</div>`
  const deviceAsset = `<div><span style='color:#8A93A9'>所属资产：</span>${assetDto?.name || '-'}</div>`
  markerLabel?.remove()
  markerLabel = new AMap.Text({
    position: [longitude, latitude],
    anchor: 'bottom-right',
    offset: [0, -40],
    text: `<div><span style='color:#8A93A9'>${pName}编号：</span>${gxCode || '-'}</div>
           <div><span style='color:#8A93A9'>${pName}名称：</span>${gxNmae || '-'}</div>
           ${keyName === 'device' ? deviceAsset : wellLine}`,
    style: {
      'max-width': '320px',
      'max-height': '105px',
      display: 'flex',
      padding: '20px',
      'justify-content': 'flex-start',
      'align-content': 'center',
      'flex-direction': 'column',
      background: 'rgba(230,234,243,0.4)',
      'box-shadow': '0px 2px 16px 0px rgba(0,0,0,0.1)',
      'border-radius': '16px',
      border: '1px solid #F9FBFF',
      'backdrop-filter': 'blur(10px)',
    },
  })
  Map.add(markerLabel)
}

//鼠标移出消除信息-针对点
const markerMouseOut = (e) => {
  markerLabel?.remove()
}

//鼠标移入展示信息-针对线
const lineMouseOver = (e) => {
  const { lng, lat } = e?.lnglat
  const { type, name, code } = e?.target?.getExtData()?.data || {}
  const gxType = type == '10' ? '通信管廊' : ''
  lineLabel?.remove()
  lineLabel = new AMap.Text({
    position: [lng, lat],
    anchor: 'bottom-right',
    offset: [0, -15],
    text: `<div><span style='color:#8A93A9'>管线编号：</span>${code}</div>
           <div><span style='color:#8A93A9'>管线名称：</span>${name}</div>
           <div><span style='color:#8A93A9'>管线类型：</span>${gxType}</div>`,
    style: {
      'max-width': '320px',
      'max-height': '105px',
      display: 'flex',
      padding: '20px',
      'justify-content': 'flex-start',
      'align-content': 'center',
      'flex-direction': 'column',
      background: 'rgba(230,234,243,0.4)',
      'box-shadow': '0px 2px 16px 0px rgba(0,0,0,0.1)',
      'border-radius': '16px',
      border: '1px solid #F9FBFF',
      'backdrop-filter': 'blur(10px)',
    },
  })
  Map.add(lineLabel)
}

//鼠标移出消除信息-针对线
const lineMouseOut = () => {
  lineLabel?.remove()
}

//覆盖物高亮还原
function resetLightOverLays(lx) {
  if (lx === 'line') {
    oldOverlay.map((oldover) => {
      oldover.setOptions({
        strokeColor: '#78AEEF',
        strokeWeight: 3,
        isOutline: true,
        strokeOpacity: 1,
        borderWeight: 1,
        outlineColor: '#438FFF',
      })
    })
  } else {
    oldOverlay.map((oldover) => {
      const icon = oldover.getExtData().oldIcon
      oldover.setIcon(new amap.Icon(icon))
    })
  }
  oldOverlay = []
}

/**
 * //定位到覆盖物
 * @param {*} over  覆盖物id
 * @param {*} immediately  是否立即过度
 * @param {*} lx  类型 --管线line 井jing
 */
function rowflytoOverlays(overId, immediately, lx) {
  let over
  if (lx === 'line') {
    resetLightOverLays('line')
    over = LIneMarkArr.filter((itemFil) => itemFil.getExtData().id === overId).map((item) => {
      oldOverlay.push(item)
      item.setOptions({
        strokeColor: '#78FCFF',
        strokeWeight: 3,
        isOutline: true,
        strokeOpacity: 1,
        borderWeight: 1,
        outlineColor: '#438FFF',
      })
      return item
    })
  } else {
    resetLightOverLays('jing')
    over = MarkerArr.filter((itemFil) => itemFil.getExtData().id === overId).map((item) => {
      oldOverlay.push(item)
      // let icon = new URL('../../img/jing_red.png', import.meta.url).href
      // item.setIcon(new amap.Icon)
      return item
    })
  }
  Map.setFitView(
    over, // 覆盖物数组
    immediately, // 动画过渡到制定位置
  )
}

/**
 * 打开信息弹窗
 * @param {*} position
 * @param {*} content
 */
function openInfoWindow(position, content) {
  //使用自定义窗体
  infoWindow?.close()
  // infoWindow.setAnchor('top-center')
  nextTick(() => {
    infoWindow.setContent(content)
    setTimeout(function () {
      infoWindow.open(Map, position)
    }, 200)
  })
}

defineExpose({
  openInfoWindow,
  rowflytoOverlays,
})
</script>

<style lang="scss" scoped>
.spin {
  width: 100%;
  height: 100%;
}
</style>
